﻿Imports MySQL.Data.MySqlClient
Imports MySQL.Data.Types
Public Class TMyProcedure
    Inherits TCustomMyObject
    Implements IMyRoutine

    Friend _SpecificName As String
    Friend _RoutineCatalog As String
    Friend _RoutineSchema As String
    Friend _RoutineName As String
    Friend _RoutineType As String
    Friend _DataType As String
    Friend _CharacterMaximumLength As Integer
    Friend _CharacterOctetLength As Integer
    Friend _NumericPrecision As Integer
    Friend _NumericScale As Integer
    Friend _CharacterSetName As String
    Friend _CollationName As String
    Friend _DtdIdentifier As String
    Friend _RoutineBody As String
    Friend _RoutineDefinition As String
    Friend _ExternalName As String
    Friend _ExternalLanguage As String
    Friend _ParameterStyle As String
    Friend _IsDeterministic As String
    Friend _SqlDataAccess As String
    Friend _SqlPath As String
    Friend _SecurityType As String
    Friend _Created As DateTime
    Friend _LastAltered As DateTime
    Friend _SqlMode As String
    Friend _RoutineComment As String
    Friend _Definer As String
    Friend _CharacterSetClient As String
    Friend _CollationConnection As String
    Friend _DatabaseCollation As String

    Friend _Arguments As TMyArguments

    Friend Sub New(ByVal AOwner As TCustomMyObjects, ByVal AObjectName As String)
        MyBase.New(AOwner, AObjectName)
        _Arguments = New TMyArguments(Me)
    End Sub
    Private Sub InitSource()
        MyQuery.Clear()
        MyQuery.SQL.Append("show create procedure `").Append(Me.RoutineSchema).Append("`.`").Append(Me.RoutineName).Append("`")
        MyQuery.Execute()
        _Source = MyQuery.FieldAsString("Create Procedure")
        MyQuery.Close()
    End Sub
    Public Overrides ReadOnly Property Source() As String Implements IMyRoutine.SourceText
        Get
            InitSource()
            Return _Source
        End Get
    End Property

    Public ReadOnly Property SpecificName() As String
        Get
            Return _SpecificName
        End Get
    End Property

    Public ReadOnly Property RoutineCatalog() As String
        Get
            Return _RoutineCatalog
        End Get
    End Property

    Public ReadOnly Property RoutineSchema() As String Implements IMyRoutine.RoutineSchema
        Get
            Return _RoutineSchema
        End Get
    End Property

    Public ReadOnly Property RoutineName() As String Implements IMyRoutine.RoutineName
        Get
            Return _RoutineName
        End Get
    End Property

    Public ReadOnly Property RoutineType() As String Implements IMyRoutine.RoutineType
        Get
            Return _RoutineType
        End Get
    End Property

    Public ReadOnly Property DataType() As String
        Get
            Return _DataType
        End Get
    End Property

    Public ReadOnly Property CharacterMaximumLength() As Integer
        Get
            Return _CharacterMaximumLength
        End Get
    End Property

    Public ReadOnly Property CharacterOctetLength() As Integer
        Get
            Return _CharacterOctetLength
        End Get
    End Property

    Public ReadOnly Property NumericPrecision() As Integer
        Get
            Return _NumericPrecision
        End Get
    End Property

    Public ReadOnly Property NumericScale() As Integer
        Get
            Return _NumericScale
        End Get
    End Property

    Public ReadOnly Property CharacterSetName() As String
        Get
            Return _CharacterSetName
        End Get
    End Property

    Public ReadOnly Property CollationName() As String
        Get
            Return _CollationName
        End Get
    End Property

    Public ReadOnly Property DtdIdentifier() As String
        Get
            Return _DtdIdentifier
        End Get
    End Property

    Public ReadOnly Property RoutineBody() As String
        Get
            Return _RoutineBody
        End Get
    End Property

    Public ReadOnly Property RoutineDefinition() As String Implements IMyRoutine.RoutineDefinition
        Get
            Return _RoutineDefinition
        End Get
    End Property

    Public ReadOnly Property ExternalName() As String
        Get
            Return _ExternalName
        End Get
    End Property

    Public ReadOnly Property ExternalLanguage() As String
        Get
            Return _ExternalLanguage
        End Get
    End Property

    Public ReadOnly Property ParameterStyle() As String
        Get
            Return _ParameterStyle
        End Get
    End Property

    Public ReadOnly Property IsDeterministic() As String
        Get
            Return _IsDeterministic
        End Get
    End Property

    Public ReadOnly Property SqlDataAccess() As String
        Get
            Return _SqlDataAccess
        End Get
    End Property

    Public ReadOnly Property SqlPath() As String
        Get
            Return _SqlPath
        End Get
    End Property

    Public ReadOnly Property SecurityType() As String
        Get
            Return _SecurityType
        End Get
    End Property

    Public ReadOnly Property Created() As DateTime
        Get
            Return _Created
        End Get
    End Property

    Public ReadOnly Property LastAltered() As DateTime
        Get
            Return _LastAltered
        End Get
    End Property

    Public ReadOnly Property SqlMode() As String
        Get
            Return _SqlMode
        End Get
    End Property

    Public ReadOnly Property RoutineComment() As String Implements IMyRoutine.RoutineComment
        Get
            Return _RoutineComment
        End Get
    End Property

    Public ReadOnly Property Definer() As String Implements IMyRoutine.Definer
        Get
            Return _Definer
        End Get
    End Property

    Public ReadOnly Property CharacterSetClient() As String
        Get
            Return _CharacterSetClient
        End Get
    End Property

    Public ReadOnly Property CollationConnection() As String
        Get
            Return _CollationConnection
        End Get
    End Property

    Public ReadOnly Property DatabaseCollation() As String
        Get
            Return _DatabaseCollation
        End Get
    End Property

    Public ReadOnly Property Arguments() As TMyArguments Implements IMyRoutine.Arguments
        Get
            Return _Arguments
        End Get
    End Property

    Public ReadOnly Property Query() As TMyQuery Implements IMyRoutine.Query
        Get
            Return Me.MyQuery
        End Get
    End Property

    Public ReadOnly Property SQLText() As String Implements IMyRoutine.SQLText
        Get
            Return "call `" & Me.RoutineSchema & "`.`" & Me.RoutineName & "`(" & GetArgumentString() & ")"
        End Get
    End Property

    Public Sub Execute() Implements IMyRoutine.Execute
        Dim cmd As MySqlCommand = Query.Command
        cmd.CommandText = Me.SQLText
        cmd.ExecuteNonQuery()
        SetResult(cmd)
        cmd.Parameters.Clear()
        cmd.CommandText = String.Empty
    End Sub

    Private Sub SetResult(ByRef ACmd As MySqlCommand)
        For i As Integer = 0 To ACmd.Parameters.Count - 1
            Dim arg As TMyArgument = _Arguments.ItemByName(ACmd.Parameters(i).ParameterName)
            arg.Value = ACmd.Parameters(i).Value
        Next
    End Sub

    Private Sub SetParam(ByRef ACmd As MySqlCommand)
        ACmd.Parameters.Clear()
        For i As Integer = 0 To _Arguments.Count - 1
            Dim param As New MySqlParameter
            Select Case _Arguments(i).ParameterMode
                Case "IN"
                    param.ParameterName = _Arguments(i).ParameterName
                    param.Direction = ParameterDirection.Input
                    param.Value = _Arguments(i).Value
                Case "OUT"
                    param.ParameterName = _Arguments(i).ParameterName
                    param.Direction = ParameterDirection.Output
                Case "INOUT"
                    param.ParameterName = _Arguments(i).ParameterName
                    param.Direction = ParameterDirection.InputOutput
                    param.Value = _Arguments(i).Value
                Case "RETURNS"
                    param.Direction = ParameterDirection.ReturnValue
            End Select
            ACmd.Parameters.Add(param)
        Next
    End Sub

    Private Function GetArgumentString() As String
        Dim s As String = String.Empty
        For i As Integer = 0 To _Arguments.Count - 1
            If i = 0 Then
                s = "?" & _Arguments(i).ParameterName
            Else
                s &= ",?" & _Arguments(i).ParameterName
            End If
        Next
        Return s
    End Function
End Class
